package FrameWork;

import com.jogamp.opengl.util.texture.Texture;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import static javax.media.opengl.GL2GL3.GL_QUADS;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.glu.GLU;
import utils.Vector3;

/**
 *
 * @author trong_000
 */
public class Global {
    
    private static Global instance = null;
    private Global(){}
    
    public static Global getIns(){
        if(instance == null){
            instance = new Global();
        }
        return instance;
    }
    public static boolean isFullScreen = false;
    public static int FPS = 60;
    public static String title = "OpenGL Chess 3D";
    public static int wndWidth = 1366; 
    public static int wndHeight = 768; 
    public static GLAutoDrawable drawable = null;
    
    public static Random random = new Random(System.currentTimeMillis());

   public static GLU glu = new GLU();
    public static GL getGL() {
        return drawable.getGL();
    }        

    public static void drawCube(Texture tt,float x,float y,float z){
        GL2 gl = drawable.getGL().getGL2();  // get the OpenGL 2 graphics context
        drawCube(tt, x, y, z, 1, 1, 1);
        /*gl.glPushMatrix();
         * gl.glLoadIdentity();  // reset the model-view matrix
         * gl.glTranslatef(x, y, z); // translate into the screen
         * tt.enable(gl);
         * tt.bind(gl);
         * gl.glBegin(GL_QUADS);
         * // Front Face
         * 
         * gl.glTexCoord2f(0.0f, 0.0f);
         * gl.glVertex3f(-1.0f, -1.0f,  1.0f);  // Bottom Left Of The Texture
         * gl.glTexCoord2f(1.0f, 0.0f);
         * gl.glVertex3f( 1.0f, -1.0f,  1.0f);  // Bottom Right Of The Texture
         * gl.glTexCoord2f(1.0f, 1.0f);
         * gl.glVertex3f( 1.0f,  1.0f,  1.0f);  // Top Right Of The Texture and Quad
         * gl.glTexCoord2f(0.0f, 1.0f);
         * gl.glVertex3f(-1.0f,  1.0f,  1.0f);  // Top Left Of The Texture and Quad
         * 
         * // Back Face
         * 
         * gl.glTexCoord2f(1.0f, 0.0f);
         * gl.glVertex3f(-1.0f, -1.0f, -1.0f);
         * gl.glTexCoord2f(1.0f, 1.0f);
         * gl.glVertex3f(-1.0f, 1.0f, -1.0f);
         * gl.glTexCoord2f(0.0f, 1.0f);
         * gl.glVertex3f(1.0f, 1.0f, -1.0f);
         * gl.glTexCoord2f(0.0f, 0.0f);
         * gl.glVertex3f(1.0f, -1.0f, -1.0f);
         * 
         * // Top Face
         * gl.glTexCoord2f(0.0f, 1.0f);
         * gl.glVertex3f(-1.0f, 1.0f, -1.0f);
         * gl.glTexCoord2f(0.0f, 0.0f);
         * gl.glVertex3f(-1.0f, 1.0f, 1.0f);
         * gl.glTexCoord2f(1.0f, 0.0f);
         * gl.glVertex3f(1.0f, 1.0f, 1.0f);
         * gl.glTexCoord2f(1.0f, 1.0f);
         * gl.glVertex3f(1.0f, 1.0f, -1.0f);
         * 
         * // Bottom Face
         * gl.glTexCoord2f(1.0f, 1.0f);
         * gl.glVertex3f(-1.0f, -1.0f, -1.0f);
         * gl.glTexCoord2f(0.0f, 1.0f);
         * gl.glVertex3f(1.0f, -1.0f, -1.0f);
         * gl.glTexCoord2f(0.0f, 0.0f);
         * gl.glVertex3f(1.0f, -1.0f, 1.0f);
         * gl.glTexCoord2f(1.0f, 0.0f);
         * gl.glVertex3f(-1.0f, -1.0f, 1.0f);
         * 
         * // Right face
         * gl.glTexCoord2f(1.0f, 0.0f);
         * gl.glVertex3f(1.0f, -1.0f, -1.0f);
         * gl.glTexCoord2f(1.0f, 1.0f);
         * gl.glVertex3f(1.0f, 1.0f, -1.0f);
         * gl.glTexCoord2f(0.0f, 1.0f);
         * gl.glVertex3f(1.0f, 1.0f, 1.0f);
         * gl.glTexCoord2f(0.0f, 0.0f);
         * gl.glVertex3f(1.0f, -1.0f, 1.0f);
         * 
         * // Left Face
         * gl.glTexCoord2f(0.0f, 0.0f);
         * gl.glVertex3f(-1.0f, -1.0f, -1.0f);
         * gl.glTexCoord2f(1.0f, 0.0f);
         * gl.glVertex3f(-1.0f, -1.0f, 1.0f);
         * gl.glTexCoord2f(1.0f, 1.0f);
         * gl.glVertex3f(-1.0f, 1.0f, 1.0f);
         * gl.glTexCoord2f(0.0f, 1.0f);
         * gl.glVertex3f(-1.0f, 1.0f, -1.0f);
         * 
         * gl.glEnd();
         * 
         * gl.glPopMatrix();*/
    }
    
    public static void drawCube(Texture tt, float x, float y, float z,
        float sx, float sy, float sz) {
        sy = sx * Global.wndWidth/Global.wndHeight;
        GL2 gl = Global.drawable.getGL().getGL2();
        gl.glPushMatrix();
        
        gl.glTranslatef(x, y, z);
        tt.enable(gl);
        tt.bind(gl);
        
        gl.glBegin(GL2.GL_QUADS);        // Draw The Cube Using quads
        {
            // Front Face
         
            gl.glTexCoord2f(0.0f, 0.0f);
            gl.glVertex3f(-sx, -sy,  sz);  // Bottom Left Of The Texture
            gl.glTexCoord2f(1.0f, 0.0f);
            gl.glVertex3f( sx, -sy,  sz);  // Bottom Right Of The Texture
            gl.glTexCoord2f(1.0f, 1.0f);
            gl.glVertex3f( sx,  sy,  sz);  // Top Right Of The Texture and Quad
            gl.glTexCoord2f(0.0f, 1.0f);
            gl.glVertex3f(-sx,  sy,  sz);  // Top Left Of The Texture and Quad
            
             // Back Face
          
            gl.glTexCoord2f(1.0f, 0.0f);
            gl.glVertex3f(-sx, -sy, -sz);
            gl.glTexCoord2f(1.0f, 1.0f);
            gl.glVertex3f(-sx, sy, -sz);
            gl.glTexCoord2f(0.0f, 1.0f);
            gl.glVertex3f(sx, sy, -sz);
            gl.glTexCoord2f(0.0f, 0.0f);
            gl.glVertex3f(sx, -sy, -sz);

                // Top Face
            gl.glTexCoord2f(0.0f, 1.0f);
            gl.glVertex3f(-sx, sy, -sz);
            gl.glTexCoord2f(0.0f, 0.0f);
            gl.glVertex3f(-sx, sy, sz);
            gl.glTexCoord2f(1.0f, 0.0f);
            gl.glVertex3f(sx, sy, sz);
            gl.glTexCoord2f(1.0f, 1.0f);
            gl.glVertex3f(sx, sy, -sz);

            // Bottom Face
           gl.glTexCoord2f(1.0f, 1.0f);
           gl.glVertex3f(-sx, -sy, -sz);
           gl.glTexCoord2f(0.0f, 1.0f);
           gl.glVertex3f(sx, -sy, -sz);
           gl.glTexCoord2f(0.0f, 0.0f);
           gl.glVertex3f(sx, -sy, sz);
           gl.glTexCoord2f(1.0f, 0.0f);
           gl.glVertex3f(-sx, -sy, sz);

                // Right face
            gl.glTexCoord2f(1.0f, 0.0f);
            gl.glVertex3f(sx, -sy, -sz);
            gl.glTexCoord2f(1.0f, 1.0f);
            gl.glVertex3f(sx, sy, -sz);
            gl.glTexCoord2f(0.0f, 1.0f);
            gl.glVertex3f(sx, sy, sz);
            gl.glTexCoord2f(0.0f, 0.0f);
            gl.glVertex3f(sx, -sy, sz);

             // Left Face
            gl.glTexCoord2f(0.0f, 0.0f);
            gl.glVertex3f(-sx, -sy, -1.0f);
            gl.glTexCoord2f(1.0f, 0.0f);
            gl.glVertex3f(-sx, -sy, sz);
            gl.glTexCoord2f(1.0f, 1.0f);
            gl.glVertex3f(-sx, sy, sz);
            gl.glTexCoord2f(0.0f, 1.0f);
            gl.glVertex3f(-sx, sy, -sz);
        }
        gl.glEnd();            // End Drawing The Cube
        tt.disable(gl);
        
        gl.glPopMatrix();
        gl.glColor4f(1, 1, 1, 1);
    }

    /**
     * Ve he truc Oxyz
     */
    public static void drawAxes() {
        GL2 gl = Global.drawable.getGL().getGL2();
        gl.glBegin(GL2.GL_LINES);

        gl.glColor3f(1.0f, 0.5f, 0.5f);
        gl.glVertex3f(0f, 0f, 0f);
        gl.glVertex3f(15f, 0f, 0f);

        gl.glColor3f(0.5f, 1.0f, 0.5f);
        gl.glVertex3f(0f, 0f, 0f);
        gl.glVertex3f(0f, 15f, 0f);

        gl.glColor3f(0.5f, 0.5f, 1.0f);
        gl.glVertex3f(0f, 0f, 0f);
        gl.glVertex3f(0f, 0f, 15f);

        gl.glEnd();
    }
    
    /**
     * Vẽ 1 khối cube đủ màu có tọa độ x,y,z
     * @param x
     * @param y
     * @param z 
     */
    public static void drawCube(float x, float y, float z) {
        
        GL2 gl = getGL().getGL2();
        gl.glPushMatrix();
        //gl.glLoadIdentity();  // reset the model-view matrix
        gl.glTranslatef(x, y, z); // translate into the screen
        
        gl.glPushMatrix();
        gl.glColor3f(0, 0, 1); // AZ
        gl.glRotatef(180f, 0, 1, 0);
        drawFace(gl);
        gl.glPopMatrix();

        gl.glPushMatrix();
        gl.glColor3f(0, 1, 0); // VE
        gl.glRotatef(0f, 0, 1, 0);
        drawFace(gl);
        gl.glPopMatrix();

        gl.glPushMatrix();
        gl.glColor3f(0, 1, 1); // CE
        gl.glRotatef(-90f, 0, 1, 0);
        drawFace(gl);
        gl.glPopMatrix();

        gl.glPushMatrix();
        gl.glColor3f(1, 0, 0); // RO
        gl.glRotatef(90f, 0, 1, 0);
        drawFace(gl);
        gl.glPopMatrix();

        gl.glPushMatrix();
        gl.glColor3f(1, 0, 1); // MA
        gl.glRotatef(-90f, 1, 0, 0);
        drawFace(gl);
        gl.glPopMatrix();

        gl.glPushMatrix();
        gl.glColor3f(1, 1, 0); // AM
        gl.glRotatef(90f, 1, 0, 0);
        drawFace(gl);
        gl.glPopMatrix();
        gl.glPopMatrix();
  }

    public static void drawCube(Vector3 pos){
        drawCube(pos.x,pos.y,pos.z);
    }
    /**
     * Vẽ 1 mặt (hình chữ nhật) với kích thước cố định
     * @param gl 
     */
    private static void drawFace(GL2 gl) {
        gl.glBegin(GL2.GL_QUADS);
        gl.glVertex3f(-0.5f, -0.5f, +0.5f);
        gl.glVertex3f(+0.5f, -0.5f, +0.5f);
        gl.glVertex3f(+0.5f, +0.5f, +0.5f);
        gl.glVertex3f(-0.5f, +0.5f, +0.5f);
        gl.glEnd();
  }
    
    /**
     * Vẽ 1 hình chữ nhật với kích thước size
     * @param gl
     * @param size 
     */
    private static void drawFace(GL2 gl,float size) {
        gl.glBegin(GL2.GL_QUADS);
        gl.glVertex3f(-size, -size, +size);
        gl.glVertex3f(+size, -size, +size);
        gl.glVertex3f(+size, +size, +size);
        gl.glVertex3f(-size, +size, +size);
        gl.glEnd();
  }
  
}
